﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Pixysoft.Framework.Configurations;

namespace Pixysoft.Framework.Logs.Controller
{
    /// <summary>
    /// 只能对html可以识别 但是xml无法识别的内容进行格式化 例如特殊字符串等
    /// html解析使用了stirng流解析
    /// </summary>
    class LogFormatController
    {
        private static volatile LogFormatController instance;

        private static object syncRoot = new Object();

        public static LogFormatController Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                        {
                            instance = new LogFormatController();
                        }
                    }
                }
                return instance;
            }
        }

        public void Format(string filepath, string filename, bool crossfiles)
        {
            foreach (string file in GetSearchFiles(filepath, filename, crossfiles))
            {
                string content = Read(file);

                if (string.IsNullOrEmpty(content))
                    continue;

                try
                {
                    IHtmlDocument doc = HtmlManager.Deserialize(content);

                    foreach (IHtmlNode node in doc.Node)
                    {
                        Format(node);
                    }

                    Write(file, doc.Serialize(true));
                }
                catch
                {
                }
            }
        }

        private void Format(IHtmlNode node)
        {
            foreach (IHtmlNode subnode in node.Node)
            {
                Format(subnode);
            }

            node.Text = StringHelper.RegularLogContent(node.Text);

            node.RawAttribute = StringHelper.RegularLogAttribute(node.RawAttribute);
        }

        private List<string> GetSearchFiles(string filepath, string filename, bool crossFiles)
        {
            List<string> list = new List<string>();

            if (File.Exists(filepath + filename + StringHelper.default_log_postfix))
                list.Add(filepath + filename + StringHelper.default_log_postfix);

            if (!crossFiles)
            {
                return list;
            }

            foreach (string file in GetCrossFiles(filepath, filename))
            {
                list.Add(file);
            }

            return list;
        }

        private List<string> GetCrossFiles(string filepath, string filename)
        {
            List<string> list = new List<string>();

            if (!Directory.Exists(filepath))
                return list;

            foreach (string file in Directory.GetFiles(filepath))
            {
                string dfilename = StringFilter.GetFileName(file);

                if (string.IsNullOrEmpty(dfilename))
                    continue;

                if (dfilename.Equals(filename + StringHelper.default_log_postfix, StringComparison.OrdinalIgnoreCase))
                    continue;

                if (!dfilename.EndsWith(StringHelper.default_log_postfix, StringComparison.OrdinalIgnoreCase))
                    continue;

                if (!dfilename.StartsWith(filename, StringComparison.OrdinalIgnoreCase))
                    continue;

                list.Add(file);
            }

            list.Sort();

            return list;
        }


        private string Write(string pathfilename, string content)
        {
            if (string.IsNullOrEmpty(pathfilename))
                return null;

            using (FileStream sw = File.Open(pathfilename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                StreamWriter writer = new StreamWriter(sw, Encoding.UTF8);

                writer.Write(content);

                writer.Flush();

                writer.Close();

                writer.Dispose();
            }

            return content;

        }

        private string Read(string pathfilename)
        {
            if (string.IsNullOrEmpty(pathfilename))
                return null;

            if (!File.Exists(pathfilename))
            {
                return null;
            }

            string content = null;

            using (FileStream sw = File.Open(pathfilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                StreamReader reader = new StreamReader(sw);

                content = reader.ReadToEnd();

                reader.Close();

                reader.Dispose();
            }

            return content;
        }
    }
}
